package com.melodyframe.stage.annotation;

import java.lang.reflect.Method;
import java.util.List;

import com.melodyframe.common.context.util.ContextUtil;
import com.melodyframe.common.tools.bean.BeanMethodUtil;
import com.melodyframe.stage.core.CommonStage;
import com.melodyframe.stage.core.performer.BeanProxyPerformer;

public class AnnotationStage extends CommonStage {
	public void addNamespace(com.melodyframe.stage.core.Stage bean) {
		Stage stageAnnotation = bean.getClass().getAnnotation(Stage.class);
		String namespace = stageAnnotation.namespace();
		this.addNamespace(namespace, bean);
	}

	public void addComponentBean(Object bean) {
		Component componentAnnotation = bean.getClass().getAnnotation(
				Component.class);
		String path = componentAnnotation.path();
		List<Method> performerMethods = BeanMethodUtil.getMethodsForAnnotation(
				bean.getClass(), Performer.class);
		for (Method proxyMethod : performerMethods) {
			this.addPerformerProxy(bean, proxyMethod, path);
		}
		List<Method> filterMethods = BeanMethodUtil.getMethodsForAnnotation(
				bean.getClass(), Filter.class);
		for (Method filterMethod : filterMethods) {
			this.addFilterProxy(bean, filterMethod);
		}

	}

	public void addPerformerProxy(Object bean, Method proxyMethod,
			String basePath) {
		Performer performerAnnotation = proxyMethod
				.getAnnotation(Performer.class);
		String path = performerAnnotation.path();
		if ("".equals(path)) {
			path = "/" + proxyMethod.getName();
		}
		this.addPerformer(basePath + path,
				createPerformerFromMethod(bean, proxyMethod));
	}

	public void addFilterProxy(Object bean, Method proxyMethod) {
		Filter filterAnnotation = proxyMethod.getAnnotation(Filter.class);
		this.addFilter(filterAnnotation.order(),
				createPerformerFromMethod(bean, proxyMethod));
	}

	private BeanProxyPerformer createPerformerFromMethod(Object bean,
			Method proxyMethod) {
		BeanProxyPerformer performer = new BeanProxyPerformer();
		performer.setBean(bean);
		performer.setMethod(proxyMethod);
		performer.setParamaterRequests(ContextUtil
				.getParameterRequestsFromMethod(proxyMethod));
		return performer;
	}

}
